﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using Ict.DataAccess.Attributes;

namespace Ict.DataAccess.Linq
{
    //class TableMapperFactory
    //{
    //    private TableMapperFactory()
    //    {
    //    }

    //    public static ITableMapper CreateTableMapper<T>(T type)
    //    {
    //        return new TableMapper<T>();
    //    }
    //}

    //interface ITableMapper
    //{
    //    string TableName { get; }
    //    string QueryName { get; }
    //    Dictionary<string, string> FieldMap { get; }
    //}

    /// <summary>
    /// 数据类和数据表之间(ORM)的映射关系
    /// </summary>
    /// <typeparam name="T">数据类类型</typeparam>
    public class TableMapper<T>
    {
        static TableMapper()
        {
            tableName = ExtractTableName(typeof(T));
            queryName = ExtractQueryName(typeof(T));

            tableFieldMap = new Dictionary<string, string>();
            queryFieldMap = new Dictionary<string, string>();

            ExtractFieldMap(typeof(T), ref queryFieldMap, ref tableFieldMap);
        }

        /// <summary>
        /// 初始化类型对应的查询名称和表名称
        /// </summary>
        #region 初始化类型对应的查询名称和表名称

        private static string tableName;

        private static string ExtractTableName(Type type)
        {
            object[] attrs = type.GetCustomAttributes(typeof(TableNameAttribute), false);
            if (attrs != null && attrs.Length > 0)
                return ((TableNameAttribute)attrs[0]).Value;
            else
                return type.Name;
        }

        private static string queryName;

        private static string ExtractQueryName(Type type)
        {
            object[] attrs = type.GetCustomAttributes(typeof(QueryNameAttribute), false);
            if (attrs != null && attrs.Length > 0)
                return ((QueryNameAttribute)attrs[0]).Value;
            else
            {
                return tableName;
            }
        }

        #endregion 初始化类型对应的查询名称和表名称

        /// <summary>
        /// 初始化字段和类属性的映射关系
        /// </summary>
        #region 初始化字段和类属性的映射关系

        private static Dictionary<string, string> queryFieldMap;

        private static Dictionary<string, string> tableFieldMap;

        private static void ExtractFieldMap(Type type,
            ref Dictionary<string, string> queryFieldMap,
            ref Dictionary<string, string> tableFieldMap)
        {
            DmlEncoder encoder = DataContext.Current.CreateSqlEncoder();

            PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo info in propertyInfos)
            {
                try
                {
                    bool isReadonly = false;
                    string fieldName = encoder.ExtractFieldName(info, ref isReadonly);
                    if (fieldName != null)
                    {
                        queryFieldMap.Add(info.Name, fieldName);
                        if (!isReadonly)
                            tableFieldMap.Add(info.Name, fieldName);
                    }
                }
                catch
                {
                }
            }
        }

        #endregion 初始化字段和类属性的映射关系

        #region TableMapper静态属性

        public static string TableName
        {
            get { return TableMapper<T>.tableName; }
        }

        public static string QueryName
        {
            get { return TableMapper<T>.queryName; }
        }

        public static Dictionary<string, string> QueryFieldMap
        {
            get { return TableMapper<T>.queryFieldMap; }
        }

        public static Dictionary<string, string> TableFieldMap
        {
            get { return TableMapper<T>.tableFieldMap; }
        }

        #endregion TableMapper静态属性
    }
}
